package com.googlecode.jyoutubeuploader.parser;

import org.apache.commons.lang3.Validate;
import org.apache.log4j.Logger;

import com.googlecode.jyoutubeuploader.to.YouTubeArgumentsTo;
import com.googlecode.jyoutubeuploader.util.FileCreator;
import com.googlecode.jyoutubeuploader.util.StringUtils;
import com.googlecode.jyoutubeuploader.util.category.CategoryParser;

public class DefaultArgumentMapper implements ArgumentMapper{

	private CommandLineParser commandLineParser;
	private Logger logger;
	private FileCreator fileCreator;
	private CategoryParser categoryParser;
	
	public YouTubeArgumentsTo mapArguments() {
		YouTubeArgumentsTo args = new YouTubeArgumentsTo();
		mapUsername(args);
		mapPassword(args);
		mapFile(args);
		mapCategory(args);
		mapTitle(args);
		mapPrivacy(args);
		mapDescription(args);
		mapKeywords(args);
		mapThrottleSpeed(args);
		mapReportInterval(args);
		return args;
	}

	protected void mapReportInterval(YouTubeArgumentsTo args) {
		String reportingIntervalString = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.REPORT_INTERVAL_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.REPORT_INTERVAL_ARG_SHORT)); 
		int reportingInterval = 10;
		if (reportingIntervalString != null){
			reportingInterval = Integer.parseInt(reportingIntervalString);
		}
		args.setReportingInterval(reportingInterval);
		logger.debug("Reporting interval has been set to: " + (reportingInterval <= 0 ? "off" : reportingInterval + " seconds"));
	}

	protected void mapThrottleSpeed(YouTubeArgumentsTo args) {
		String throttleSpeedString = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.THROTTLE_SPEED_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.THROTTLE_SPEED_ARG_SHORT)); 
		int throttleSpeed = 0;
		if (throttleSpeedString != null){
			throttleSpeed = Integer.parseInt(throttleSpeedString);
		}
		args.setThrottleSpeed(throttleSpeed);
		logger.debug("Throttle speed has been set to: " + (throttleSpeed <= 0 ? "unlimited" : throttleSpeed + "kbps"));
	}

	protected void mapKeywords(YouTubeArgumentsTo args) {
		String keywordString = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.KEYWORDS_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.KEYWORDS_ARG_SHORT)); 
		String[] keywords = keywordString.split(",");
		args.setKeywords(keywords);
		logger.debug("Keywords have been set to: " + StringUtils.join(keywords, ", "));
	}

	protected void mapDescription(YouTubeArgumentsTo args) {
		String description = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.DESCRIPTION_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.DESCRIPTION_ARG_SHORT)); 
		
		args.setDescription(description);
		logger.debug("Description has been set to: \"" + description + "\".");
	}

	protected void mapPrivacy(YouTubeArgumentsTo args) {
		String privacy = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.PRIVACY_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.PRIVACY_ARG_SHORT)); 
		
		boolean isPrivate = Boolean.parseBoolean(privacy);
		args.setPrivate(isPrivate);
		logger.debug("Privacy has been set to: " + (isPrivate ? "private" : "public"));
	}

	protected void mapTitle(YouTubeArgumentsTo args) {
		String title = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.TITLE_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.TITLE_ARG_SHORT)); 
		
		args.setTitle(title);
		logger.debug("Title has been set to: " + title);
	}
	
	protected void mapCategory(YouTubeArgumentsTo args) {
		String category = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.CATEGORY_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.CATEGORY_ARG_SHORT)); 
		
		args.setCategory(categoryParser.parse(category));
		logger.debug("Category has been set to: " + category);
	}
	
	protected void mapFile(YouTubeArgumentsTo args) {
		String file = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.FILE_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.FILE_ARG_SHORT)); 
		
		args.setFile(fileCreator.createFile(file));
		logger.debug("File has been set to: " + file);
	}

	protected void mapPassword(YouTubeArgumentsTo args) {
		String password = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.PASSWORD_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.PASSWORD_ARG_SHORT)); 
		
		args.setPassword(password);
		logger.debug("Password has been set to: " + password);
	}

	protected void mapUsername(YouTubeArgumentsTo args) {
		Validate.isTrue(commandLineParser.containsKey(
				ModifiedCommandLineParser.USERNAME_ARG_SHORT
				, ModifiedCommandLineParser.USERNAME_ARG_LONG));
		
		String username = StringUtils.coalesce(
				commandLineParser.getValue(ModifiedCommandLineParser.USERNAME_ARG_LONG)
				, commandLineParser.getValue(ModifiedCommandLineParser.USERNAME_ARG_SHORT)); 
		
		args.setUsername(username);
		logger.debug("Username has been set to: " + username);
	}

	public void setCommandLineParser(CommandLineParser commandLineParser) {
		this.commandLineParser = commandLineParser;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	public void setFileCreator(FileCreator fileCreator) {
		this.fileCreator = fileCreator;
	}

	public void setCategoryParser(CategoryParser categoryParser) {
		this.categoryParser = categoryParser;
	}

}
